package com.example.authsystem.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

@Schema(
        name = "RegisterRequest",
        description = "用户注册请求数据传输对象，包含创建新用户账户所需的基本信息",
        example = """
                {
                  "username": "john_smith",
                  "email": "john.smith@example.com",
                  "password": "securePass123"
                }
                """
)
public class RegisterRequest {

    @Schema(
            description = """
                    用户名，作为用户在系统中的唯一标识符。
                    - 必须在系统中唯一
                    - 只能包含字母、数字和下划线
                    - 建议使用有意义且容易记忆的名称
                    """,
            example = "john_smith",
            requiredMode = Schema.RequiredMode.REQUIRED,
            minLength = 3,
            maxLength = 20,
            pattern = "^[a-zA-Z0-9_]+$",
            title = "用户名"
    )
    @NotBlank(message = "Username is required")
    @Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")
    @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "Username can only contain letters, numbers and underscores")
    private String username;

    @Schema(
            description = """
                    用户邮箱地址，用于账户验证、登录凭据和系统通知。
                    - 必须是有效的邮箱格式
                    - 必须在系统中唯一
                    - 将用作主要的账户标识和通信方式
                    - 注册后需要进行邮箱验证（如果启用）
                    """,
            example = "john.smith@example.com",
            requiredMode = Schema.RequiredMode.REQUIRED,
            format = "email",
            maxLength = 255,
            title = "邮箱地址"
    )
    @NotBlank(message = "Email is required")
    @Email(message = "Email should be valid")
    @Size(max = 255, message = "Email length should not exceed 255 characters")
    private String email;

    @Schema(
            description = """
                    用户登录密码，用于账户安全验证。
                    密码安全建议：
                    - 至少包含一个大写字母、小写字母和数字
                    - 避免使用常见密码或个人信息
                    - 定期更换密码以提高安全性
                    - 密码将被安全加密存储，系统无法查看原始密码
                    """,
            example = "securePass123",
            requiredMode = Schema.RequiredMode.REQUIRED,
            minLength = 6,
            maxLength = 40,
            format = "password",
            accessMode = Schema.AccessMode.WRITE_ONLY,
            title = "登录密码"
    )
    @NotBlank(message = "Password is required")
    @Size(min = 6, max = 40, message = "Password must be between 6 and 40 characters")
    @Pattern(
            regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d@$!%*?&]{6,40}$",
            message = "Password must contain at least one lowercase letter, one uppercase letter, and one number"
    )
    private String password;

    /**
     * 默认构造函数
     */
    public RegisterRequest() {
    }

    /**
     * 全参数构造函数
     *
     * @param username 用户名
     * @param email    邮箱地址
     * @param password 密码
     */
    public RegisterRequest(String username, String email, String password) {
        this.username = username;
        this.email = email;
        this.password = password;
    }

    // Getters and Setters

    /**
     * 获取用户名
     *
     * @return 用户名
     */
    public String getUsername() {
        return username;
    }

    /**
     * 设置用户名
     *
     * @param username 用户名
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * 获取邮箱地址
     *
     * @return 邮箱地址
     */
    public String getEmail() {
        return email;
    }

    /**
     * 设置邮箱地址
     *
     * @param email 邮箱地址
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * 获取密码
     *
     * @return 密码
     */
    public String getPassword() {
        return password;
    }

    /**
     * 设置密码
     *
     * @param password 密码
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * 重写toString方法，隐藏敏感信息
     */
    @Override
    public String toString() {
        return "RegisterRequest{" +
                "username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", password='[PROTECTED]'" +  // 不显示密码明文
                '}';
    }

    /**
     * 重写equals方法
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        RegisterRequest that = (RegisterRequest) obj;

        if (!username.equals(that.username)) return false;
        if (!email.equals(that.email)) return false;
        return password.equals(that.password);
    }

    /**
     * 重写hashCode方法
     */
    @Override
    public int hashCode() {
        int result = username.hashCode();
        result = 31 * result + email.hashCode();
        result = 31 * result + password.hashCode();
        return result;
    }
}